package com.takeaway.utils.myconnectionpool;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 后台赖骏
 */
public class MyDataBaseImpl extends AbstractMyDataBaseImpl {
    private static final List<PoolAgent> IDLE_COLLECTIONS =new ArrayList<>();

    private static final List<PoolAgent> ACTIVE_COLLECTIONS =new ArrayList<>();

    final static int MAX_IDLE_COLLECTIONS_NUM = 10;

    final static int MAX_ACTIVE_COLLECTIONS_NUM = 5;

    final static int MAX_TIME_OUT_WAIT = 30000;

    final Object monitor1 = new Object();

    public MyDataBaseImpl(String username, String password, String url) {
        super(username, password, url);
    }

    @Override
    public Connection getConnection() throws SQLException {
        PoolAgent poolAgent = new PoolAgent(super.getConnection(),this);
        return poolAgent.getAgent();
    }
        @Override
        public PoolAgent getAgentConnection() throws SQLException {
                PoolAgent poolAgent = null;
                boolean wait = false;

                while (poolAgent==null){
                    synchronized (monitor1){

                        if (!IDLE_COLLECTIONS.isEmpty()){
                            poolAgent = IDLE_COLLECTIONS.remove(0);
                        }
                        else if (ACTIVE_COLLECTIONS.size()<MAX_ACTIVE_COLLECTIONS_NUM){
                           poolAgent = new PoolAgent(super.getConnection(),this);
                        }
                    }


                    if (!wait){
                        wait = true;
                    }
                    if (poolAgent == null){
                        try {
                            monitor1.wait(MAX_TIME_OUT_WAIT);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            break;
                        }

                    }

                }
                 if (poolAgent!=null){
                     ACTIVE_COLLECTIONS.add(poolAgent);
                 }
        return poolAgent;
        }
        @Override
        public void closeConnection(PoolAgent poolAgent){
            synchronized (monitor1){
                ACTIVE_COLLECTIONS.remove(poolAgent);
                if (IDLE_COLLECTIONS.size()<MAX_IDLE_COLLECTIONS_NUM){
                    IDLE_COLLECTIONS.add(poolAgent);
                }
                else {
                    try {
                        poolAgent.getConnection().close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                monitor1.notify();
            }
        }
}
